package com.study.ThreadPoolExecutor;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

import com.study.ThreadPoolExecutor.annoations.ThreadSafe;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description: 线程不安全的类，反面案例
 * @author Administrator
 *
 */
@Slf4j
@ThreadSafe
public class AtomicExample {

	//请求总数
	public static int clientTotal = 5000;
	//同时并发执行数
	public static int threadTotal = 200;
	
	//public static int count = 0;
	public static AtomicInteger count = new AtomicInteger(0);
	
	public static void main(String[] args) throws InterruptedException{
		
		System.out.println("start:");
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); //创建线程池
		
		final Semaphore semaphore = new Semaphore(threadTotal);  //semaphore信号量，允许并发的数目
		CountDownLatch countDownLatch = new CountDownLatch(clientTotal); //闭锁，计数器，传入请求总数
		for(int i = 0; i< clientTotal; i ++){
			newCachedThreadPool.execute(()->{
				try{
					//信号量，acquire()时表示，当前线程数是否允许被执行，如果达到了一定并发数，这个add()方法将被阻塞
					//Semaphore是计数信号量。Semaphore管理一系列许可证。
					//每个acquire方法阻塞，直到有一个许可证可以获得然后拿走一个许可证；每个release方法增加一个许可证，这可能会释放一个阻塞的acquire方法。
					semaphore.acquire();
					add();
					semaphore.release();//信号量，执行完后，要释放当前线程release()
				}catch (Exception e) {
					log.error("exception : ", e);
				}
				countDownLatch.countDown(); //每执行完一个线程，计数器减一
			});
		}
		
		countDownLatch.await(); //countDownLatch.await()方法保证当前计数器为0，也就是所有的线程已经执行完
		newCachedThreadPool.shutdown(); //关闭线程池
		log.info("count:{}",count); 
		System.out.println("end.");
	}
	public static void add(){
		count.getAndIncrement();
		System.out.println("count：" + count);
		//count.incrementAndGet();
	}
}
